package io.renren.modules.test.usecase.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.common.utils.R;
import io.renren.modules.module.entity.Module;
import io.renren.modules.module.entity.vo.AllModule;
import io.renren.modules.module.service.ModuleServicex;
import io.renren.modules.sys.controller.AbstractController;
import io.renren.modules.sys.entity.SysRoleEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.SysUserRoleEntity;
import io.renren.modules.sys.service.SysRoleService;
import io.renren.modules.sys.service.SysUserRoleService;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.test.library.entity.Library;
import io.renren.modules.test.library.service.LibraryService;
import io.renren.modules.test.usecase.entity.UseCase;
import io.renren.modules.test.usecase.entity.UseCaseLibrary;
import io.renren.modules.test.usecase.entity.UseCaseVo;
import io.renren.modules.test.usecase.service.CaseLibraryService;
import io.renren.modules.test.usecase.service.CaseService;
import io.renren.modules.test.usecase.utils.CaseUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author liyinuo
 * 测试用例
 */
@RestController
@RequestMapping("/case")
@Api(tags = "测试用例管理")
public class CaseController extends AbstractController {
    @Autowired
    private CaseService caseService;
    @Autowired
    private CaseLibraryService caseLibraryService;
    @Autowired
    private LibraryService libraryService;
    @Autowired
    private ModuleServicex moduleService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    SysUserRoleService sysUserRoleService;
    @Autowired
    SysRoleService sysRoleService;
    @PostMapping("/insert")
    @ApiImplicitParam(value = "鉴权token",name = "token",paramType = "header", dataType = "String", required=true)
    @ApiOperation("新建测试用例")
    @RequiresPermissions("case:save")
    public R insertCase(@RequestBody UseCase useCase,
                        @RequestParam(name="libraryId") Long libraryId){
        caseService.save(useCase);
        UseCaseLibrary caseLibrary = new UseCaseLibrary();
        caseLibrary.setLibraryId(libraryId);
        caseLibrary.setCaseId(useCase.getCaseId());
        caseLibraryService.save(caseLibrary);
        return R.ok("添加成功");
    }

    @GetMapping("/delete/{id}")
    @ApiImplicitParam(value = "鉴权token",name = "token",paramType = "header", dataType = "String", required=true)
    @ApiOperation("删除测试用例")
    @Transactional
    @RequiresPermissions("case:delete")
    public R deleteCase(@PathVariable("id") Long id){
        caseService.removeById(id);
        caseLibraryService.remove(new QueryWrapper<UseCaseLibrary>().eq("case_id",id));
        return R.ok("删除成功");
    }

    @PostMapping("/update")
    @ApiImplicitParam(value = "鉴权token",name = "token",paramType = "header", dataType = "String", required=true)
    @ApiOperation("修改测试用例")
    @RequiresPermissions("case:update")
    public R updateCase(@RequestBody UseCase useCase){
        caseService.updateById(useCase);
        return R.ok("修改成功");
    }

    @GetMapping("/list")
    @ApiImplicitParam(value = "鉴权token",name = "token",paramType = "header", dataType = "String", required=true)
    @ApiOperation("分页查询")
    @RequiresPermissions("case:list")
    public R listCase(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                      @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                      @RequestParam(name="libaryId") Long libaryId,
                      @RequestParam(name="CaseTitle", defaultValue="") String CaseTitle){
        Page<UseCase> page = new Page<>(pageNo, pageSize);
        IPage<UseCase> pageList = caseService.page(page, new LambdaQueryWrapper<UseCase>()
                .likeRight(UseCase::getCaseTitle,CaseTitle));
        List<UseCase> caseList = pageList.getRecords();
        //如果是角色是管理员或者是产品经理那么就直接返回全部的用例
        SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
        String roleName = null;
        if (!sysUserEntity.getUsername().equals("admin")){
            //获取userid
            Long userId = sysUserEntity.getUserId();
            //获取当前用户的角色
            SysUserRoleEntity sysUserRoleServiceOne = sysUserRoleService.getOne(new LambdaQueryWrapper<SysUserRoleEntity>()
                    .eq(SysUserRoleEntity::getUserId, userId));
            Long roleId = sysUserRoleServiceOne.getRoleId();
            SysRoleEntity role = sysRoleService.getById(roleId);
            roleName = role.getRoleName();
        }

        if ( !(sysUserEntity.getUsername().equals("admin") || roleName.equals("产品经理"))) {
            //根据指定测试库下的测试用例
            List<Long> caseIds = caseLibraryService.list(new LambdaQueryWrapper<UseCaseLibrary>()
                            .eq(UseCaseLibrary::getLibraryId, libaryId)).stream().map(item -> item.getCaseId())
                    .collect(Collectors.toList());
            caseList = caseList.stream().filter(caseVo -> caseIds.contains(caseVo.getCaseId()))
                    .filter(caseVo -> caseVo.getTestUser().equals(getUserId())).collect(Collectors.toList());

        }else {
            //根据指定测试库下的测试用例
            List<Long> caseIds = caseLibraryService.list(new LambdaQueryWrapper<UseCaseLibrary>()
                            .eq(UseCaseLibrary::getLibraryId, libaryId)).stream().map(item -> item.getCaseId())
                    .collect(Collectors.toList());
            caseList = caseList.stream().filter(caseVo -> caseIds.contains(caseVo.getCaseId()))
                    .collect(Collectors.toList());

        }

        List<UseCaseVo> voList = new ArrayList<>();
        for (UseCase useCase : caseList) {
            UseCaseVo useCaseVo = new UseCaseVo();
            useCaseVo.setCaseId(useCase.getCaseId());
            useCaseVo.setLibraryName((libraryService.getById(caseLibraryService.selectLibraryByCase(useCase.getCaseId()))).getLibraryName());
            useCaseVo.setCaseTitle(useCase.getCaseTitle());
            useCaseVo.setCaseDesc(useCase.getCaseDesc());
            useCaseVo.setCaseStatus(CaseUtils.statusUtils(useCase.getCaseStatus()));
            useCaseVo.setCaseLevel(CaseUtils.levelUtils(useCase.getCaseLevel()));
            useCaseVo.setCaseTime(useCase.getCaseTime());
            useCaseVo.setModuleName(moduleService.getById(useCase.getModuleId()).getModuleName());
            useCaseVo.setTestUserName(sysUserService.getById(useCase.getTestUser()).getUsername());
            useCaseVo.setCreateTime(useCase.getCreateTime());
            voList.add(useCaseVo);
        }

        return R.ok("200").put("data",voList).put("total",pageList.getTotal());
    }

    @GetMapping("/selectOne/{id}")
    @RequiresPermissions("case:info")
    @ApiImplicitParam(value = "鉴权token",name = "token",paramType = "header", dataType = "String", required=true)
    @ApiOperation("通过id查询单个")
    public R selectOne(@PathVariable("id") Long id){
        UseCase useCase = caseService.getById(id);
        Library library = libraryService.getById(caseLibraryService.selectLibraryByCase(useCase.getCaseId()));
        return R.ok("200").put("data",useCase).put("library",library);
    }
    @GetMapping("/selectLibraryByCase/{id}")
    @RequiresPermissions("case:selectLibraryByCase")
    @ApiImplicitParam(value = "鉴权token",name = "token",paramType = "header", dataType = "String", required=true)
    @ApiOperation("通过用例id查询对应测试库")
    public R selectLibraryByCase(@PathVariable("id") Long id){
        Long libraryId = caseLibraryService.selectLibraryByCase(id);
        return R.ok("200").put("data",libraryId);
    }

}
